/*
 * Copyright (c) 2022  by Junzhao
 * THIS FILE IS PART OF JAVASE Song Huongkang PROJECT
 * All Rights Reserved.
 */

package 处理流.其他流.随机存取文件流;

import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @Description 随机存取文件流
 * RandomAccessFile 声明在java.io包下，但直接继承于java.lang.Object类。
 * 并且它实现了DataInput、DataOutput这两个接口，也就意味着这个类既可以读也可以写。
 *
 * RandomAccessFile 类支持 “随机访问” 的方式，程序可以直接跳到文件的任意地方来读、写文件
 *      支持只访问文件的部分内容
 *      可以向已存在的文件后追加内容
 * RandomAccessFile 对象包含一个记录指针，用以标示当前读写处的位置。
 * RandomAccessFile 类对象可以自由移动记录指针：
 * long getFilePointer()：获取文件记录指针的当前位置
 * void seek(long pos)：将文件记录指针定位到 pos 位置
 * <p>
 * 构造器
 * public RandomAccessFile(File file, String mode)
 * public RandomAccessFile(String name, String mode)
 * <p>
 * 创建 RandomAccessFile 类实例需要指定一个 mode 参数，
 * 该参数指定 RandomAccessFile 的访问模式：
 * r: 以只读方式打开
 * rw：打开以便读取和写入
 * rwd:打开以便读取和写入；同步文件内容的更新
 * rws:打开以便读取和写入；同步文件内容和元数据的更新
 * 如果模式为只读r。则不会创建文件，而是会去读取一个已经存在的文件，
 * 如果读取的文件不存在则会出现异常。 如果模式为rw读写。
 * 如果文件不存在则会去创建文件，如果存在则不会创建。
 *
 * 我们可以用RandomAccessFile这个类，来实现一个多线程断点下载的功能，
 * 用过下载工具的朋友们都知道，下载前都会建立两个临时文件，
 * 一个是与被下载文件大小相同的空文件，另一个是记录文件指针的位置文件，每次暂停的时候，
 * 都会保存上一次的指针，然后断点下载的时候，会继续从上一次的地方下载，
 * 从而实现断点下载或上传的功能，有兴趣的朋友们可以自己实现下。—.=
 * @Author 俊昭
 * @Date 2022/4/28
 */
public class RandomAccessFileTest {
    @Test
    public void test001() throws IOException {
        // 造对象
        RandomAccessFile r1 = new RandomAccessFile("C:\\Users\\Junzhao\\IOStream\\新建文件夹\\实例视频.mkv", "r");
        RandomAccessFile r2 = new RandomAccessFile("C:\\Users\\Junzhao\\IOStream\\随机存取文件流\\实例视频2.mkv", "rw");

        // 读写
        byte[] buf = new byte[1024];
        int len;
        while ((len=r1.read(buf))!=-1){
            r2.write(buf,0,len);
        }

        // 关闭流
        r1.close();
        r2.close();
    }
    @Test
    public void test002() throws IOException {

        RandomAccessFile r1 = new RandomAccessFile("C:\\Users\\Junzhao\\IOStream\\随机存取文件流\\1.txt", "rw");
//        RandomAccessFile r2 = new RandomAccessFile("C:\\Users\\Junzhao\\IOStream\\随机存取文件流\\2.txt", "rw");

        r1.seek(3);
        r1.write("xyz".getBytes(StandardCharsets.UTF_8));
//        r2.write("xyz".getBytes(StandardCharsets.UTF_8));
        // 作为输出流 如果对象文件不存在会创建一个 如果存在且有内容会从头覆盖
        r1.close();

    }
    @Test
    public void test003() throws IOException{
        // 实现插入
        // 造对象
        File file = new File("C:\\Users\\Junzhao\\IOStream\\随机存取文件流\\1.txt");
        RandomAccessFile r1 = new RandomAccessFile(file, "rw");
//        RandomAccessFile w1 = new RandomAccessFile(file, "rw");

//        // 将文件内容保存到r1的bytes数组中缓存
//        byte[] bytes = new byte[64];
//        int read = r1.read(bytes);
//        // 存入插入前位置的数据
//        w1.write(bytes,0,3);
//        // 插入数据
//        w1.write("xyz".getBytes(StandardCharsets.UTF_8));
//        // 存入剩余数据
//        w1.write(bytes,4,read-3);
//        // 关闭流
//        r1.close();
//        w1.close();
        byte[] buf = new byte[64];
        int len;
        StringBuilder sb = new StringBuilder((int) file.length());
        r1.seek(3);
        while((len=r1.read(buf))!=-1){
            sb.append(new String(buf,0,len));
        }
        r1.seek(3);
        r1.write("123123".getBytes(StandardCharsets.UTF_8));
        r1.write(sb.toString().getBytes(StandardCharsets.UTF_8));






    }
}
